#ifndef _TJMATRIX752011_H_
#define _TJMATRIX752011_H_

template <typename T, int R = 4, int C = 4>
class raw_matrix {
	typedef T Type;
	static const int Raw = R;
	static const int Column = C;

	union {
		struct {
			Type r00, r01, r02, tx;
			Type r10, r11, r12, ty;
			Type r20, r21, r22, tz;
			Type m0,  m1,  m2,  m3;
		};

		Type data[4][4];
	};

	// this prototype is created just for the constructor?
	raw_matrix() {
		for (int i = 0; i < 15; i ++) {
			data[i/4][i%4] = 0;
		}
		data[3][3] = 1;
	}
};

template <typename T>
class raw_matrix<T, 3, 4>
{
	typedef T Type;
	static const int Raw = 3;
	static const int Column = 4;

	union {
		struct {
			Type r00, r01, r02, tx;
			Type r10, r11, r12, ty;
			Type r20, r21, r22, tz;
		};

		Type data[3][4];
	};

	// this prototype is created just for the constructor?
	raw_matrix() {
		for (int i = 0; i < 3; i ++) 
			for (int j = 0; i < 4; j ++)
				data[i][j] = 0;
	}
};

template <typename T>
class raw_matrix<T, 3, 3>
{
	typedef T Type;
	static const int Raw = 3;
	static const int Column = 3;

	union {
		struct {
			Type r00, r01, r02;
			Type r10, r11, r12;
			Type r20, r21, r22;
		};

		Type data[3][3];
	};

	// this prototype is created just for the constructor?
	raw_matrix() {
		for (int i = 0; i < 3; i ++) 
			for (int j = 0; i < 3; j ++)
				data[i][j] = 0;
	}
};

template <typename T, int R, int C>
class matrix: public raw_matrix<T, R, C>
{
public:
	typedef T Type;
	static const int Raw = R;
	static const int Colomn = C;

public:
	matrix(): raw_matrix() {};

	matrix(const matrix& other) {
		for (int i = 0; i < Raw; i ++) 
			for (int j = 0; j < Colomn; j ++) 
				data[i][j] = other.data[i][j];
	}

	const Type* getPointer() const {
		return &data[0][0];
	}

	Type* getPointer() {
		return &data[0][0];
	}
};

#endif // _TJMATRIX752011_H_